//#include "Discovering/SubGraphMatch.h"
#include "Discovering/GFDDiscovering.h"
#include "GFDMatch/GFDCompare.h"
#include <ctime>

void GFDDiscoveringTest(std::string fileName,
                        std::string resultFileName,
                        int support) {
    Graph DataGraph(fileName);
    std::set<int> suppList{0};
    GFDDiscovering gfdDiscovering(DataGraph);
    gfdDiscovering.patternGrow(suppList, support, resultFileName);
}

void VF2Test() {
    Graph Pattern("../Sample/queryGraph01");
    Graph DataGraph("../Sample/dataGraph01");

    VF2 vf2(Pattern, DataGraph);
    vf2.vf2Engine([&](std::map<int, int> &matchState) {
        std::cout << "Matched\n";
        for (auto i: matchState) {
            std::cout << "(" << i.first << ", " << i.second << ") ";
        }
        std::cout << std::endl;
        return true;
    }, defaultPruneCheck);
}

void GFDFileIOTest() {
    std::ifstream ifstream("result2");
    std::ofstream ofstream("testResult");
    std::vector<GFD> gfd;

    GFD tmpGFD;
    while (!ifstream.eof()) {
        ifstream >> tmpGFD;
        if (ifstream.eof())break;
        gfd.push_back(tmpGFD);
        tmpGFD.fileOut(ofstream);
        tmpGFD._pattern.clear();
        tmpGFD._literalPairVector.clear();
    }
    ifstream.close();
    for (auto &i : gfd) {
        std::cout << i << std::endl;
    }
}

void GFDCompareTest(std::string file1, std::string file2) {

    std::vector<GFD> gfd1Vector, gfd2Vector, ansGFDVector;
    {
        std::ifstream ifstream(file1);

        GFD tmpGFD;
        while (!ifstream.eof()) {
            ifstream >> tmpGFD;
            if (ifstream.eof())break;
            gfd1Vector.push_back(tmpGFD);
            tmpGFD._pattern.clear();
            tmpGFD._literalPairVector.clear();
        }
        ifstream.close();
    }
    {
        std::ifstream ifstream(file2);

        GFD tmpGFD;
        while (!ifstream.eof()) {
            ifstream >> tmpGFD;
            if (ifstream.eof())break;
            gfd2Vector.push_back(tmpGFD);
            tmpGFD._pattern.clear();
            tmpGFD._literalPairVector.clear();
        }
        ifstream.close();
    }
    for (auto &gfd1:gfd1Vector) {
        for (auto &gfd2:gfd2Vector) {
            GFD tmpGFD;
            if (GFDCompare(gfd1, gfd2, tmpGFD)) {
                ansGFDVector.push_back(tmpGFD);
                std::cout << tmpGFD << std::endl;
                break;
            }
        }
    }
}

int main() {

    GFD::_maxXLiteralVectorSize = 2;
    GFD::_maxYLiteralVectorSize = 1;
    GFD::_maxVertexSize = 3;
    GFD::_maxEdgeSize = 2;
    GFD::_maxLiteralSize = 6;


    clock_t startTime, endTime;
    startTime = clock();

//    VF2Test();

//    GFDFileIOTest();

    GFDDiscoveringTest("../Sample/dblp1960",
                       "resultDBLP1960_2_3_50_200",
                       50);
//    GFDDiscoveringTest("../Sample/dblp1960",
//                       "../Result/resultDBLP1960",
//                       1000);
//    GFDDiscoveringTest("../Sample/dataGraph01", "result1",4);

//    GFDCompareTest("../Result/result1", "../Result/result2");
    endTime = clock();

    unsigned int second = (endTime - startTime) / CLOCKS_PER_SEC;
    unsigned int minutes = second / 60 % 60;
    unsigned int hours = second / 60 / 60;
    second %= 60;
    std::cout << "The run time is: "
              << hours << "h " << minutes << "m " << second << " s"
              << std::endl;

    return 0;
}